package com.mysql.injector.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import org.apache.ibatis.annotations.Param;

/**
 * 基于MP的 BaseMapper 新增了1个方法： insertBatchSomeColumn
 *
 * @param <T> 实体
 */
public interface SuperMapper<T> extends BaseMapper<T> {

  /**
   * 批量插入所有字段
   * <p>
   * 只测试过MySQL！只测试过MySQL！只测试过MySQL！
   *
   * @param entityList 实体对象集合
   * @return 插入成功记录数
   */
  int insertBatchSomeColumn(List<T> entityList);

  /**
   * 批量替换插入所有字段
   * <p>
   * 只测试过MySQL！只测试过MySQL！只测试过MySQL！
   *
   * @param entityList 实体对象集合
   * @return 插入成功记录数
   */
  int replaceIntoBatchSomeColumn(@Param(Constants.COLL) List<T> entityList);

  /**
   * 批量插入所有字段（重复存在忽略插入）
   * <p>
   * 只测试过MySQL！只测试过MySQL！只测试过MySQL！
   *
   * @param entityList 实体对象集合
   * @return 插入成功记录数
   */
  int insertIgnoreBatchSomeColumn(@Param(Constants.COLL) List<T> entityList);

  /**
   * 插入所有字段（重复存在忽略插入）
   * <p>
   * 只测试过MySQL！只测试过MySQL！只测试过MySQL！
   *
   * @param entity 实体对象
   * @return 插入成功记录数
   */
  int insertIgnore(T entity);

  default int insertOnDuplicateKeyUpdate(T entity) {
    return insertOnDuplicateKeyUpdate(entity, (Map<String, Object>)null);
  }

  default int insertOnDuplicateKeyUpdate(T entity, Collection<String> columnList) {
    return insertOnDuplicateKeyUpdate(entity,
      columnList.stream().collect(Collectors.toMap(Function.identity(), s -> String.format("VALUES(`%s`)", s))));
  }

  /**
   * 插入所有字段（重复存在更新）
   *
   * @param entity 实体对象
   * @return 插入成功记录数
   */
  int insertOnDuplicateKeyUpdate(@Param(Constants.ENTITY) T entity,
    @Param(Constants.COLUMN_MAP) Map<String, Object> map);

  default int insertOnDuplicateKeyUpdateBatchSomeColumn(List<T> entityList, Collection<String> columnList) {
    return insertOnDuplicateKeyUpdateBatchSomeColumn(entityList,
      columnList.stream().collect(Collectors.toMap(Function.identity(), s -> String.format("VALUES(`%s`)", s))));
  }

  /**
   * 批量插入所有字段（重复存在更新）
   *
   * @param entityList 实体对象集合
   * @return 插入成功记录数
   */
  int insertOnDuplicateKeyUpdateBatchSomeColumn(@Param(Constants.COLLECTION) List<T> entityList,
    @Param(Constants.COLUMN_MAP) Map<String, Object> map);
}
